package util;



import java.awt.geom.Point2D;
import java.util.ArrayList;

public class RasterRegion implements Comparable<RasterRegion> 
{
    public String Tag = null;
    public int regId = 0;
    public ArrayList<Point2D> points = new ArrayList<Point2D>();

    public Boolean momentiOdredjeni = false;
    public int n = 0;  // ukupan broj tacaka

    public double c20 = 0;
    public double c11 = 0;
    public double c02 = 0;

    public int minX = Integer.MAX_VALUE;
    public int maxX = 0;
    public int minY = Integer.MAX_VALUE;
    public int maxY = 0;

    //osnovne statisticke osobine regiona
    public double xM = 0;
    public double yM = 0;
    public double theta = 0;
    public double eccentricity = 0;
    public double majorAxisLength = 0;
    public double minorAxisLength = 0;
  

    public void odrediMomente()
    {
        xM = 0;
        yM = 0;
        theta = 0;
        eccentricity = 0;
        majorAxisLength = 0;
        minorAxisLength = 0;
        n = points.size();
        for (Point2D pp : points)
        {
            xM += pp.getX();
            yM += pp.getY();

            // odredi "minimum bounding box" regiona
            if (pp.getX() < minX)
                minX = (int) pp.getX();
            if (pp.getX() > maxX)
                maxX = (int) pp.getX();
            if (pp.getY() < minY)
                minY = (int) pp.getY();
            if (pp.getY() > maxY)
                maxY = (int) pp.getY();
        }
        xM = xM / n;
        yM = yM / n;
        for (Point2D pp : points)
        {
            c20 += (pp.getX() - xM) * (pp.getX() - xM);
            c11 += (pp.getX() - xM) * (pp.getY() - yM);
            c02 += (pp.getY() - yM) * (pp.getY() - yM);
        }
        // sad imamo vrednosti covariance matrix
        // c20 c11
        // c11 c02
        // odrediti karakteristicne vrednosti
        double a = 1;
        double b = -(c20 + c02);
        double c = c20 * c02 - c11 * c11;
        double D = b * b - 4 * c;
        double alfa1 = 0;
        double alfa2 = 0;
        if (D > 0)
        {
            D = Math.sqrt(D);
            alfa1 = (-b + D) / 2 * a;
            alfa2 = (-b - D) / 2 * a;
            double temp1 = Math.max(alfa1, alfa2);
            double temp2 = Math.min(alfa1, alfa2);
            alfa1 = temp1;
            alfa2 = temp2;
            if (alfa1 != 0)
                eccentricity = alfa2 / alfa1;
            majorAxisLength = alfa1;
            minorAxisLength = alfa2;
        }
        theta = 0.5 * Math.atan2(2 * c11, (c20 - c02));
    }

    public short[][] odrediSliku()
    {
        if (!momentiOdredjeni)
            odrediMomente();

        int height = maxY - minY + 1;
        int width = maxX - minX + 1;

        short[][] retVal = new short[height][ width];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                retVal[i][j] = (short) 255;
            }
        }

        for (Point2D p : points)
        {
            retVal[(int) (p.getY() - minY)][(int) (p.getX() - minX)] = 0;
        }

        return retVal;
    }

    public short[][] odrediNSliku()
    {
        if (!momentiOdredjeni)
            odrediMomente();

        ArrayList<Point2D> nPoints = new ArrayList<Point2D>();

        double ugao = Math.PI / 2 - Math.abs(theta);
        for (Point2D p : points)
        {
            double nX = Math.cos(ugao) * (p.getX() - xM) - Math.sin(ugao) * (p.getY() - yM) + xM;
            double nY = Math.sin(ugao) * (p.getX() - xM) + Math.cos(ugao) * (p.getY() - yM) + yM;

            nPoints.add(new Point2D.Double(nX, nY));
        }

        RasterRegion nRegion = new RasterRegion();
        nRegion.points = nPoints;

        return nRegion.odrediSliku();
    }
    

	@Override
	public int compareTo(RasterRegion o) {
		// TODO Auto-generated method stub
		  return Integer.valueOf(this.minX).compareTo(Integer.valueOf(o.minX));
	}

}
